package cn.itsource.pethome.base.service.impl;

import cn.itsource.pethome.base.domain.dto.VerifyDTO;
import cn.itsource.pethome.base.service.IImageVerifyService;
import cn.itsource.pethome.constants.BaseConstants;
import cn.itsource.pethome.user.domain.User;
import cn.itsource.pethome.user.mapper.UserMapper;
import cn.itsource.pethome.util.BusinessException;
import cn.itsource.pethome.util.StrUtils;
import cn.itsource.pethome.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class ImageVerifyServiceImpl implements IImageVerifyService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String imageVerifyCode(String key) {
        try {
            //1.判断key是否为null
            if(StringUtils.isEmpty(key)){
                throw new BusinessException("非法访问");
            }
            //2.生成code
            String code = StrUtils.getComplexRandomString(4);
            //3.生成图片验证码
            String verifyCode = VerifyCodeUtils.VerifyCode(110, 40, code);
            //4.将code存到redis里面    REGISTER:xxxxxx
            redisTemplate.opsForValue().set(BaseConstants.register.REGISTER+key,code,5, TimeUnit.MINUTES);
            return verifyCode;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("生成验证码失败");
        }
        return null;
    }

    /**
     *
     * @param verifyDTO
     */
    @Override
    public void sendSmsCode(VerifyDTO verifyDTO) {
        //1.验证手机号是否为null
        if(StringUtils.isEmpty(verifyDTO.getPhone())){
            throw new BusinessException("手机号不能为空");
        }
        if(verifyDTO.getType() == 1){
            imgCodeVerify(verifyDTO);
        }else {
            sendCode(verifyDTO);
        }
    }

    /**
     * 注册发送短信验证
     * @param verifyDTO
     */
    private void imgCodeVerify(VerifyDTO verifyDTO) {
        //2.验证图片码是否为null
        if(StringUtils.isEmpty(verifyDTO.getImageCode())){
            throw new BusinessException("图片验证码不能为空");
        }
        //3.图片验证码的key是否为null
        if(StringUtils.isEmpty(verifyDTO.getImageCodeKey())){
            throw new BusinessException("非法访问");
        }

        //4.去校验图片验证码和redis中的图片验证码是否一致
        Object imgVerifyCode = redisTemplate.opsForValue()
                .get(BaseConstants.register.REGISTER + verifyDTO.getImageCodeKey());
        if(imgVerifyCode == null){
            throw new BusinessException("图片验证码已过期");
        }
        //equalsIgnoreCase 忽略大小写
        if(!imgVerifyCode.toString().equalsIgnoreCase(verifyDTO.getImageCode())){
            throw new BusinessException("图片验证码错误");
        }
        //5.去数据库里面校验 手机号是否存在
        User user = userMapper.queryByPhone(verifyDTO.getPhone());
        sendCode(BaseConstants.register.REGISTER+verifyDTO.getPhone(),user);
    }

    /**
     * 绑定发送短信验证
     * @param verifyDTO
     */
    private void sendCode(VerifyDTO verifyDTO) {
        User user = userMapper.queryByPhoneUnWxUser(verifyDTO.getPhone());
        sendCode(BaseConstants.register.BINDER+verifyDTO.getPhone(),user);
    }

    /**
     * 真实发送短信验证码 和 保存redis
     * @param key
     */
    public void sendCode(String key,User user){
        //5.1 抛出业务异常 手机号已存在 请去登录
        if(user != null){
            throw new BusinessException("该手机号已注册，请去登录");
        }
        //6.1.2 生成一个key 手机号+业务键
        //6.去redis中去查询是否存在验证码
        Object smsCode = redisTemplate.opsForValue().get(key);
        //6.1.1 生成一个验证码
        String randomCode = StrUtils.getRandomString(4);
        //6.1不存在验证码
        if(smsCode == null ){//表示第一次进来
            //6.1.3 生成一个value  code+时间戳   （时间戳做重复发送短信的校验）
            long currentTime = System.currentTimeMillis();
            String value = randomCode +":"+ currentTime;// 9527:13245647812448614
            redisTemplate.opsForValue().set(key,value,3,TimeUnit.MINUTES);//3分钟有效
        }else{ //6.2存在验证码
            //6.2.1 判断当前整个key是否超过1分钟
            String[] split = smsCode.toString().split(":");
            String oldTime = split[1];
            if((System.currentTimeMillis() - Long.parseLong(oldTime)) < 1000 * 60){//6.2.1.2  不超过 抛出异常
                throw new BusinessException("请勿重复获取验证码");
            }
            //6.2.1.1  超过 重写生成发送短信验证码 更新时间戳(把之前的取出来)
            redisTemplate.opsForValue().set(key,split[0] +":"+ System.currentTimeMillis(),3,TimeUnit.MINUTES);//3分钟有效
            randomCode = split[0];
        }
        //发送短信验证码
//        SendMsgUtil.sendMsg(verifyDTO.getPhone(),randomCode);
        System.out.println(randomCode);
    }
}
